<?php
/**
 * NegativeProductTargetingApi
 * PHP version 5
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */

/**
 * Amazon Ads API - Sponsored Brands
 *
 * Use the Amazon Ads API for Sponsored Brands for campaign, ad group, keyword, negative keyword, drafts, Stores, landing pages, and Brands management operations. For more information about Sponsored Brands, see the [Sponsored Brands Support Center](https://advertising.amazon.com/help#GQFZA83P55P747BZ). For onboarding information, see the [account setup](https://advertising.amazon.com/API/docs/v3/guides/account_setup) topic.
 *
 * OpenAPI spec version: 3.0
 * 
 * Generated by:https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api.git
 * AmazonAdvertisingApi Codegen version: 3.0.51
 */
/**
 * NOTE: This class is auto generated by the AmazonAdvertisingApi code generator program.
 *https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 * Do not edit the class manually.
 */

namespace AmazonAdvertisingApi\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use AmazonAdvertisingApi\ApiException;
use AmazonAdvertisingApi\Configuration;
use AmazonAdvertisingApi\HeaderSelector;
use AmazonAdvertisingApi\ObjectSerializer;

/**
 * NegativeProductTargetingApi Class Doc Comment
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */
class NegativeProductTargetingApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     */
    public function __construct(
        ClientInterface $client = null,
        Configuration $config = null,
        HeaderSelector $selector = null
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: new Configuration();
        $this->headerSelector = $selector ?: new HeaderSelector();
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation archiveNegativeTarget
     *
     * Archives a negative target specified by identifier. Note that archiving is permanent, and once a negative target has been archived it can't be made active again.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id negative_target_id (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\SBTargetingClauseResponse
     */
    public function archiveNegativeTarget($negative_target_id)
    {
        list($response) = $this->archiveNegativeTargetWithHttpInfo($negative_target_id);
        return $response;
    }

    /**
     * Operation archiveNegativeTargetWithHttpInfo
     *
     * Archives a negative target specified by identifier. Note that archiving is permanent, and once a negative target has been archived it can't be made active again.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\SBTargetingClauseResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function archiveNegativeTargetWithHttpInfo($negative_target_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBTargetingClauseResponse';
        $request = $this->archiveNegativeTargetRequest($negative_target_id);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\SBTargetingClauseResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation archiveNegativeTargetAsync
     *
     * Archives a negative target specified by identifier. Note that archiving is permanent, and once a negative target has been archived it can't be made active again.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function archiveNegativeTargetAsync($negative_target_id)
    {
        return $this->archiveNegativeTargetAsyncWithHttpInfo($negative_target_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation archiveNegativeTargetAsyncWithHttpInfo
     *
     * Archives a negative target specified by identifier. Note that archiving is permanent, and once a negative target has been archived it can't be made active again.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function archiveNegativeTargetAsyncWithHttpInfo($negative_target_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBTargetingClauseResponse';
        $request = $this->archiveNegativeTargetRequest($negative_target_id);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'archiveNegativeTarget'
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function archiveNegativeTargetRequest($negative_target_id)
    {
        // verify the required parameter 'negative_target_id' is set
        if ($negative_target_id === null || (is_array($negative_target_id) && count($negative_target_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $negative_target_id when calling archiveNegativeTarget'
            );
        }

        $resourcePath = '/sb/negativeTargets/{negativeTargetId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;


        // path params
        if ($negative_target_id !== null) {
            $resourcePath = str_replace(
                '{' . 'negativeTargetId' . '}',
                ObjectSerializer::toPathValue($negative_target_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/vnd.sbnegativetarget.v3+json', 'application/vnd.sberror.v3.0+json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/vnd.sbnegativetarget.v3+json', 'application/vnd.sberror.v3.0+json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'DELETE',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation createNegativeTargets
     *
     * Create one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody1 $body A list of negative targeting clauses for creation. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\SBCreateTargetsResponse
     */
    public function createNegativeTargets($body = null)
    {
        list($response) = $this->createNegativeTargetsWithHttpInfo($body);
        return $response;
    }

    /**
     * Operation createNegativeTargetsWithHttpInfo
     *
     * Create one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody1 $body A list of negative targeting clauses for creation. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\SBCreateTargetsResponse, HTTP status code, HTTP response headers (array of strings)
     */
    public function createNegativeTargetsWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBCreateTargetsResponse';
        $request = $this->createNegativeTargetsRequest($body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\SBCreateTargetsResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation createNegativeTargetsAsync
     *
     * Create one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody1 $body A list of negative targeting clauses for creation. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createNegativeTargetsAsync($body = null)
    {
        return $this->createNegativeTargetsAsyncWithHttpInfo($body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation createNegativeTargetsAsyncWithHttpInfo
     *
     * Create one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody1 $body A list of negative targeting clauses for creation. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function createNegativeTargetsAsyncWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBCreateTargetsResponse';
        $request = $this->createNegativeTargetsRequest($body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'createNegativeTargets'
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody1 $body A list of negative targeting clauses for creation. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function createNegativeTargetsRequest($body = null)
    {

        $resourcePath = '/sb/negativeTargets';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/vnd.sbcreatenegativetargetsrequest.v3+json', 'application/vnd.sberror.v3.0+json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/vnd.sbcreatenegativetargetsrequest.v3+json', 'application/vnd.sberror.v3.0+json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getNegativeTarget
     *
     * Gets a negative target specified by identifier.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id The identifier of an existing negative target. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\SBNegativeTargetingClause
     */
    public function getNegativeTarget($negative_target_id)
    {
        list($response) = $this->getNegativeTargetWithHttpInfo($negative_target_id);
        return $response;
    }

    /**
     * Operation getNegativeTargetWithHttpInfo
     *
     * Gets a negative target specified by identifier.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id The identifier of an existing negative target. (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\SBNegativeTargetingClause, HTTP status code, HTTP response headers (array of strings)
     */
    public function getNegativeTargetWithHttpInfo($negative_target_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBNegativeTargetingClause';
        $request = $this->getNegativeTargetRequest($negative_target_id);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\SBNegativeTargetingClause',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 404:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getNegativeTargetAsync
     *
     * Gets a negative target specified by identifier.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id The identifier of an existing negative target. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getNegativeTargetAsync($negative_target_id)
    {
        return $this->getNegativeTargetAsyncWithHttpInfo($negative_target_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getNegativeTargetAsyncWithHttpInfo
     *
     * Gets a negative target specified by identifier.
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id The identifier of an existing negative target. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getNegativeTargetAsyncWithHttpInfo($negative_target_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\SBNegativeTargetingClause';
        $request = $this->getNegativeTargetRequest($negative_target_id);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getNegativeTarget'
     *
     * @param  \AmazonAdvertisingApi\Model\SBNegativeTargetId $negative_target_id The identifier of an existing negative target. (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function getNegativeTargetRequest($negative_target_id)
    {
        // verify the required parameter 'negative_target_id' is set
        if ($negative_target_id === null || (is_array($negative_target_id) && count($negative_target_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $negative_target_id when calling getNegativeTarget'
            );
        }

        $resourcePath = '/sb/negativeTargets/{negativeTargetId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;


        // path params
        if ($negative_target_id !== null) {
            $resourcePath = str_replace(
                '{' . 'negativeTargetId' . '}',
                ObjectSerializer::toPathValue($negative_target_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/vnd.sbnegativetarget.v3+json', 'application/vnd.sberror.v3.0+json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/vnd.sbnegativetarget.v3+json', 'application/vnd.sberror.v3.0+json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listNegativeTargets
     *
     * Gets a list of product negative targets associated with the client identifier passed in the authorization header, filtered by specified criteria.
     *
     * @param  \AmazonAdvertisingApi\Model\NegativeTargetsListBody $body A set of filters. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\InlineResponse20011
     */
    public function listNegativeTargets($body = null)
    {
        list($response) = $this->listNegativeTargetsWithHttpInfo($body);
        return $response;
    }

    /**
     * Operation listNegativeTargetsWithHttpInfo
     *
     * Gets a list of product negative targets associated with the client identifier passed in the authorization header, filtered by specified criteria.
     *
     * @param  \AmazonAdvertisingApi\Model\NegativeTargetsListBody $body A set of filters. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\InlineResponse20011, HTTP status code, HTTP response headers (array of strings)
     */
    public function listNegativeTargetsWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\InlineResponse20011';
        $request = $this->listNegativeTargetsRequest($body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\InlineResponse20011',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation listNegativeTargetsAsync
     *
     * Gets a list of product negative targets associated with the client identifier passed in the authorization header, filtered by specified criteria.
     *
     * @param  \AmazonAdvertisingApi\Model\NegativeTargetsListBody $body A set of filters. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listNegativeTargetsAsync($body = null)
    {
        return $this->listNegativeTargetsAsyncWithHttpInfo($body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listNegativeTargetsAsyncWithHttpInfo
     *
     * Gets a list of product negative targets associated with the client identifier passed in the authorization header, filtered by specified criteria.
     *
     * @param  \AmazonAdvertisingApi\Model\NegativeTargetsListBody $body A set of filters. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listNegativeTargetsAsyncWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\InlineResponse20011';
        $request = $this->listNegativeTargetsRequest($body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'listNegativeTargets'
     *
     * @param  \AmazonAdvertisingApi\Model\NegativeTargetsListBody $body A set of filters. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function listNegativeTargetsRequest($body = null)
    {

        $resourcePath = '/sb/negativeTargets/list';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/vnd.sblistnegativetargetsresponse.v3.2+json', 'application/vnd.sblistnegativetargetsresponse.v3+json', 'application/vnd.sberror.v3.0+json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/vnd.sblistnegativetargetsresponse.v3.2+json', 'application/vnd.sblistnegativetargetsresponse.v3+json', 'application/vnd.sberror.v3.0+json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'POST',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateNegativeTargets
     *
     * Updates one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody $body A list of negative targets with updated values. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\InlineResponse20012
     */
    public function updateNegativeTargets($body = null)
    {
        list($response) = $this->updateNegativeTargetsWithHttpInfo($body);
        return $response;
    }

    /**
     * Operation updateNegativeTargetsWithHttpInfo
     *
     * Updates one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody $body A list of negative targets with updated values. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\InlineResponse20012, HTTP status code, HTTP response headers (array of strings)
     */
    public function updateNegativeTargetsWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\InlineResponse20012';
        $request = $this->updateNegativeTargetsRequest($body);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\InlineResponse20012',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
                case 400:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Error',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation updateNegativeTargetsAsync
     *
     * Updates one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody $body A list of negative targets with updated values. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateNegativeTargetsAsync($body = null)
    {
        return $this->updateNegativeTargetsAsyncWithHttpInfo($body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateNegativeTargetsAsyncWithHttpInfo
     *
     * Updates one or more negative targets.
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody $body A list of negative targets with updated values. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateNegativeTargetsAsyncWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\InlineResponse20012';
        $request = $this->updateNegativeTargetsRequest($body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateNegativeTargets'
     *
     * @param  \AmazonAdvertisingApi\Model\SbNegativeTargetsBody $body A list of negative targets with updated values. &lt;br/&gt;Note that negative targeting clauses can be created on campaigns where serving status is not one of &#x60;archived&#x60;, &#x60;terminated&#x60;, &#x60;rejected&#x60;, or &#x60;ended&#x60;. &lt;br/&gt;Note that this operation supports a maximum list size of 100 negative targets. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function updateNegativeTargetsRequest($body = null)
    {

        $resourcePath = '/sb/negativeTargets';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;



        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/vnd.updatenegativetargetsresponse.v3+json', 'application/vnd.sberror.v3.0+json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/vnd.updatenegativetargetsresponse.v3+json', 'application/vnd.sberror.v3.0+json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

            // // this endpoint requires Bearer token
            if ($this->config->getAccessToken() !== null) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
            }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }
}
